#if _DEBUG

#include <cppunit/config/SourcePrefix.h>
#include "FollowsTest.h"

void FollowsTest::setUp()
{
}

void FollowsTest::tearDown()
{
}

CPPUNIT_TEST_SUITE_REGISTRATION( FollowsTest );

void FollowsTest::testPreInsert()
{
	Follows follows;
	STMT s7;	s7.node_type=WHILE;		s7.statement_number = 7;
	STMT s9;	s9.node_type=IF;		s9.statement_number = 9;
	
	CPPUNIT_ASSERT(-1 == follows.GetFollowing(s7).statement_number);
	CPPUNIT_ASSERT(-1 == follows.GetPrevious(s9).statement_number);
}

void FollowsTest::testGetPrevious()
{
	Follows ftable;
	STMT s1; s1.node_type=ASSIGN; s1.statement_number = 1;
	STMT s2; s2.node_type=ASSIGN; s2.statement_number = 2;
	STMT s3; s3.node_type=ASSIGN; s3.statement_number = 3;
	STMT s4; s4.node_type=ASSIGN; s4.statement_number = 4;
	STMT s5; s5.node_type=ASSIGN; s5.statement_number = 5;
	STMT s6; s6.node_type=ASSIGN; s6.statement_number = 6;
	STMT s7; s7.node_type=ASSIGN; s7.statement_number = 7;
	STMT s8; s8.node_type=ASSIGN; s8.statement_number = 8;

	ftable.InsertFollows(s1,s2);
	ftable.InsertFollows(s2,s3);
	ftable.InsertFollows(s3,s4);
	ftable.InsertFollows(s4,s5);
	ftable.InsertFollows(s5,s6);
	ftable.InsertFollows(s6,s7);
	ftable.InsertFollows(s7,s8);




	CPPUNIT_ASSERT(1 == ftable.GetPrevious(s2).statement_number);
	CPPUNIT_ASSERT(4 == ftable.GetPrevious(s5).statement_number);
	CPPUNIT_ASSERT(7 == ftable.GetPrevious(s8).statement_number);
	CPPUNIT_ASSERT(-1 == ftable.GetPrevious(s1).statement_number);
}

void FollowsTest::testGetFollowing()
{
	Follows ftable;
	STMT s1; s1.node_type=ASSIGN; s1.statement_number = 1;
	STMT s2; s2.node_type=ASSIGN; s2.statement_number = 2;
	STMT s3; s3.node_type=ASSIGN; s3.statement_number = 3;
	STMT s4; s4.node_type=ASSIGN; s4.statement_number = 4;
	STMT s5; s5.node_type=ASSIGN; s5.statement_number = 5;
	STMT s6; s6.node_type=ASSIGN; s6.statement_number = 6;
	STMT s7; s7.node_type=ASSIGN; s7.statement_number = 7;
	STMT s8; s8.node_type=ASSIGN; s8.statement_number = 8;

	ftable.InsertFollows(s1,s2);
	ftable.InsertFollows(s2,s3);
	ftable.InsertFollows(s3,s4);
	ftable.InsertFollows(s4,s5);
	ftable.InsertFollows(s5,s6);
	ftable.InsertFollows(s6,s7);
	ftable.InsertFollows(s7,s8);




	CPPUNIT_ASSERT(2 == ftable.GetFollowing(s1).statement_number);
	CPPUNIT_ASSERT(3 == ftable.GetFollowing(s2).statement_number);
	CPPUNIT_ASSERT(6 == ftable.GetFollowing(s5).statement_number);
	CPPUNIT_ASSERT(8 == ftable.GetFollowing(s7).statement_number);
	CPPUNIT_ASSERT(-1 == ftable.GetFollowing(s8).statement_number);
}

void FollowsTest::testRetrieveTransitivePrevious()
{
	Follows ftable;
	STMT s1; s1.node_type=ASSIGN; s1.statement_number = 1;
	STMT s2; s2.node_type=ASSIGN; s2.statement_number = 2;
	STMT s3; s3.node_type=ASSIGN; s3.statement_number = 3;
	STMT s4; s4.node_type=ASSIGN; s4.statement_number = 4;
	STMT s5; s5.node_type=ASSIGN; s5.statement_number = 5;
	STMT s6; s6.node_type=ASSIGN; s6.statement_number = 6;
	STMT s7; s7.node_type=ASSIGN; s7.statement_number = 7;
	STMT s8; s8.node_type=ASSIGN; s8.statement_number = 8;

	ftable.InsertFollows(s1,s2);
	ftable.InsertFollows(s2,s3);
	ftable.InsertFollows(s3,s4);
	ftable.InsertFollows(s4,s5);
	ftable.InsertFollows(s5,s6);
	ftable.InsertFollows(s6,s7);
	ftable.InsertFollows(s7,s8);




	STMT_ARRAY previous = ftable.RetrieveTransitivePrevious(s5);
	CPPUNIT_ASSERT(4 == previous.size());

	auto it = previous.find(s1);
	CPPUNIT_ASSERT(it->statement_number == 1);
	it = previous.find(s2);
	CPPUNIT_ASSERT(it->statement_number == 2);
	it = previous.find(s3);
	CPPUNIT_ASSERT(it->statement_number == 3);
	it = previous.find(s4);
	CPPUNIT_ASSERT(it->statement_number == 4);


	previous = ftable.RetrieveTransitivePrevious(s8);
	CPPUNIT_ASSERT(7 == previous.size());

	it = previous.find(s1);
	CPPUNIT_ASSERT(it->statement_number == 1);
	it = previous.find(s2);
	CPPUNIT_ASSERT(it->statement_number == 2);
	it = previous.find(s3);
	CPPUNIT_ASSERT(it->statement_number == 3);
	it = previous.find(s4);
	CPPUNIT_ASSERT(it->statement_number == 4);
	it = previous.find(s5);
	CPPUNIT_ASSERT(it->statement_number == 5);
	it = previous.find(s6);
	CPPUNIT_ASSERT(it->statement_number == 6);
	it = previous.find(s7);
	CPPUNIT_ASSERT(it->statement_number == 7);


	previous = ftable.RetrieveTransitivePrevious(s1);
	CPPUNIT_ASSERT(0 == previous.size());
}

void FollowsTest::testRetrieveTransitiveFollowing()
{
	Follows ftable;
	STMT s1; s1.node_type=ASSIGN; s1.statement_number = 1;
	STMT s2; s2.node_type=ASSIGN; s2.statement_number = 2;
	STMT s3; s3.node_type=ASSIGN; s3.statement_number = 3;
	STMT s4; s4.node_type=ASSIGN; s4.statement_number = 4;
	STMT s5; s5.node_type=ASSIGN; s5.statement_number = 5;
	STMT s6; s6.node_type=ASSIGN; s6.statement_number = 6;
	STMT s7; s7.node_type=ASSIGN; s7.statement_number = 7;
	STMT s8; s8.node_type=ASSIGN; s8.statement_number = 8;

	ftable.InsertFollows(s1,s2);
	ftable.InsertFollows(s2,s3);
	ftable.InsertFollows(s3,s4);
	ftable.InsertFollows(s4,s5);
	ftable.InsertFollows(s5,s6);
	ftable.InsertFollows(s6,s7);
	ftable.InsertFollows(s7,s8);








	STMT_ARRAY follows = ftable.RetrieveTransitiveFollowing(s4);
	CPPUNIT_ASSERT(4 == follows.size());

	auto it = follows.find(s5);
	CPPUNIT_ASSERT(it->statement_number == 5);
	it = follows.find(s6);
	CPPUNIT_ASSERT(it->statement_number == 6);
	it = follows.find(s7);
	CPPUNIT_ASSERT(it->statement_number == 7);
	it = follows.find(s8);
	CPPUNIT_ASSERT(it->statement_number == 8);



	follows = ftable.RetrieveTransitiveFollowing(s8);
	CPPUNIT_ASSERT(0 == follows.size());
	


	follows = ftable.RetrieveTransitiveFollowing(s1);
	CPPUNIT_ASSERT(7 == follows.size());

	it = follows.find(s2);
	CPPUNIT_ASSERT(it->statement_number == 2);
	it = follows.find(s3);
	CPPUNIT_ASSERT(it->statement_number == 3);
	it = follows.find(s4);
	CPPUNIT_ASSERT(it->statement_number == 4);
	it = follows.find(s5);
	CPPUNIT_ASSERT(it->statement_number == 5);
	it = follows.find(s6);
	CPPUNIT_ASSERT(it->statement_number == 6);
	it = follows.find(s7);
	CPPUNIT_ASSERT(it->statement_number == 7);
	it = follows.find(s8);
	CPPUNIT_ASSERT(it->statement_number == 8);
}


/*
void FollowsTest::testRetrieveTransitiveFollows()
{
	Follows ftable;
	STMT s1; s1.node_type=ASSIGN; s1.statement_number = 1;
	STMT s2; s2.node_type=ASSIGN; s2.statement_number = 2;
	STMT s3; s3.node_type=ASSIGN; s3.statement_number = 3;
	STMT s4; s4.node_type=ASSIGN; s4.statement_number = 4;
	STMT s5; s5.node_type=ASSIGN; s5.statement_number = 5;
	STMT s6; s6.node_type=ASSIGN; s6.statement_number = 6;
	STMT s7; s7.node_type=ASSIGN; s7.statement_number = 7;
	STMT s8; s8.node_type=ASSIGN; s8.statement_number = 8;

	ftable.InsertFollows(s1,s2);
	ftable.InsertFollows(s2,s3);
	ftable.InsertFollows(s3,s4);
	ftable.InsertFollows(s4,s5);
	ftable.InsertFollows(s5,s6);
	ftable.InsertFollows(s6,s7);
	ftable.InsertFollows(s7,s8);

	int in_array[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18};
	//int in_array2[] = {6,7,8,9,10,11,12,13,14,15,16,17,18};
	std::vector<INTEGER> in (in_array, in_array + sizeof(in_array) / sizeof(INTEGER) );
	//std::vector<INTEGER> in2 (in_array2, in_array2 + sizeof(in_array2) / sizeof(INTEGER) );
	std::vector<std::vector<INTEGER>> out = ftable.RetrieveTransitiveFollows(in,in);

	/*
	cout << "Follows*(s1,s2)" << 
		out[0].size() << ", " << out[1].size() << endl;

	unsigned int i;
	for (i = 0; i < out[0].size() ; i++)
	{
		cout << out[0][i] << ", " << out[1][i] << endl;
	}
	

	CPPUNIT_ASSERT(out[0][0]==1 && out[1][0]==2);
	CPPUNIT_ASSERT(out[0][1]==1 && out[1][1]==3);
	CPPUNIT_ASSERT(out[0][2]==1 && out[1][2]==4);
	CPPUNIT_ASSERT(out[0][3]==1 && out[1][3]==5);
	CPPUNIT_ASSERT(out[0][4]==1 && out[1][4]==6);
	CPPUNIT_ASSERT(out[0][5]==1 && out[1][5]==7);
	CPPUNIT_ASSERT(out[0][6]==1 && out[1][6]==8);
	CPPUNIT_ASSERT(out[0][7]==2 && out[1][7]==3);
	CPPUNIT_ASSERT(out[0][8]==2 && out[1][8]==4);
	CPPUNIT_ASSERT(out[0][9]==2 && out[1][9]==5);
	CPPUNIT_ASSERT(out[0][10]==2 && out[1][10]==6);
	CPPUNIT_ASSERT(out[0][11]==2 && out[1][11]==7);
	CPPUNIT_ASSERT(out[0][12]==2 && out[1][12]==8);
	CPPUNIT_ASSERT(out[0][13]==3 && out[1][13]==4);
	CPPUNIT_ASSERT(out[0][14]==3 && out[1][14]==5);
	CPPUNIT_ASSERT(out[0][15]==3 && out[1][15]==6);
	CPPUNIT_ASSERT(out[0][16]==3 && out[1][16]==7);
	CPPUNIT_ASSERT(out[0][17]==3 && out[1][17]==8);
	CPPUNIT_ASSERT(out[0][18]==4 && out[1][18]==5);
	CPPUNIT_ASSERT(out[0][19]==4 && out[1][19]==6);
	CPPUNIT_ASSERT(out[0][20]==4 && out[1][20]==7);
	CPPUNIT_ASSERT(out[0][21]==4 && out[1][21]==8);
	CPPUNIT_ASSERT(out[0][22]==5 && out[1][22]==6);
	CPPUNIT_ASSERT(out[0][23]==5 && out[1][23]==7);
	CPPUNIT_ASSERT(out[0][24]==5 && out[1][24]==8);
	CPPUNIT_ASSERT(out[0][25]==6 && out[1][25]==7);
	CPPUNIT_ASSERT(out[0][26]==6 && out[1][26]==8);
	CPPUNIT_ASSERT(out[0][27]==7 && out[1][27]==8);
}

void FollowsTest::testRetrieveFollows()
{
	Follows ftable;
	STMT s1; s1.node_type=ASSIGN; s1.statement_number = 1;
	STMT s2; s2.node_type=ASSIGN; s2.statement_number = 2;
	STMT s3; s3.node_type=ASSIGN; s3.statement_number = 3;
	STMT s4; s4.node_type=ASSIGN; s4.statement_number = 4;
	STMT s5; s5.node_type=ASSIGN; s5.statement_number = 5;
	STMT s6; s6.node_type=ASSIGN; s6.statement_number = 6;
	STMT s7; s7.node_type=ASSIGN; s7.statement_number = 7;
	STMT s8; s8.node_type=ASSIGN; s8.statement_number = 8;

	ftable.InsertFollows(s1,s2);
	ftable.InsertFollows(s2,s3);
	ftable.InsertFollows(s3,s4);
	ftable.InsertFollows(s4,s5);
	ftable.InsertFollows(s5,s6);
	ftable.InsertFollows(s6,s7);
	ftable.InsertFollows(s7,s8);

	int in_array[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18};
	//int in_array2[] = {6,7,8,9,10,11,12,13,14,15,16,17,18};
	std::vector<INTEGER> in (in_array, in_array + sizeof(in_array) / sizeof(INTEGER) );
	//std::vector<INTEGER> in2 (in_array2, in_array2 + sizeof(in_array2) / sizeof(INTEGER) );
	std::vector<std::vector<INTEGER>> out = ftable.RetrieveFollows(in,in);

	/*
	cout << "Follows(s1,s2)" << out[0].size() << ", " << out[1].size() << endl;

	unsigned int i;
	for (i = 0; i < out[0].size() ; i++)
	{
		cout << out[0][i] << ", " << out[1][i] << endl;
	}

	CPPUNIT_ASSERT(out[0][0]==1 && out[1][0]==2);
	CPPUNIT_ASSERT(out[0][1]==2 && out[1][1]==3);
	CPPUNIT_ASSERT(out[0][2]==3 && out[1][2]==4);
	CPPUNIT_ASSERT(out[0][3]==4 && out[1][3]==5);
	CPPUNIT_ASSERT(out[0][4]==5 && out[1][4]==6);
	CPPUNIT_ASSERT(out[0][5]==6 && out[1][5]==7);
	CPPUNIT_ASSERT(out[0][6]==7 && out[1][6]==8);
}
*/

#endif